home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / UI / DispTabl.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  10.0 KB  |  356 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        DispTabl.cpp
  3.  
  4.     Contains:    Implementation of class DispatchTable, which is private
  5.                 to the implementation of ODDispatcher
  6.  
  7.     Owned by:    Richard Rodseth
  8.  
  9.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  10.  
  11.     Change History (most recent first):
  12.  
  13.          <2>     9/18/96    CSL        1308996: Can't add monitors if DispatchInfo
  14.                                     doesn't exist.
  15.          <4>     5/26/95    RR        #1251403: Multithreading naming support
  16.          <3>     5/10/95    RR        # 1245459 Don't delete fDispatchModule in
  17.                                                                         ~DispatchInfo
  18.          <2>      5/2/95    RR        # 1245459 Delete fDispatchModule in
  19.                                     ~DispatchInfo
  20.          <1>     5/13/94    RR        first checked in
  21.          <1>     5/13/94    RR        first checked in
  22.         <13>      2/7/94    NP        Tiger Team doings.
  23.         <12>     12/3/93    TÇ        Stop including ODError.h, it is included
  24.                                     as ErrorDef.h inside Except.h
  25.         <11>     12/2/93    RR        Use new eventType definition
  26.         <10>     9/24/93    RR        #pragma segment
  27.          <9>     8/20/93    RR        Fixed array indexing bug
  28.          <8>     8/19/93    RR        Remove redundant workaround in destructor
  29.          <7>     8/19/93    RR        Work around apparent CFront problems with
  30.                                     delete[] in ~DispatchTable
  31.          <6>     8/19/93    NP        Work around CFront's apparent problem with
  32.                                     delete 0
  33.          <5>     8/18/93    RR        Added GetDispatchInfo/UpdateDispatchInfo
  34.          <4>     8/18/93    RR        Use DictionaryList class
  35.          <2>     8/10/93    RCR        Use OrderedCollection instead of linked list, for monitors
  36.          <1>     8/10/93    RCR        first checked in
  37.  
  38.     To Do:
  39. */
  40.  
  41. #ifndef _DISPTABL_
  42. #include "DispTabl.h"
  43. #endif
  44.  
  45. #ifndef _DISPMOD_
  46. #include "DispMod.xh"
  47. #endif
  48.  
  49. #ifndef _ORDCOLL_
  50. #include "OrdColl.h"
  51. #endif
  52.  
  53. #ifndef _DICTLIST_
  54. #include "DictList.h"
  55. #endif
  56.  
  57. #ifndef _EXCEPT_
  58. #include "Except.h"
  59. #endif
  60.  
  61. #pragma segment ODDispatcher
  62.  
  63. //=====================================================================================
  64. // Private Class: DispatchInfo
  65. //=====================================================================================
  66.  
  67. class DispatchInfo 
  68. {
  69. public:
  70.     
  71.     DispatchInfo();
  72.     
  73.         // Constructor
  74.         
  75.     ~DispatchInfo();
  76.     
  77.         // Destructor
  78.         
  79.     void SetModule(ODDispatchModule* module);
  80.     ODDispatchModule* GetModule();
  81.     void AddMonitor(ODDispatchModule* monitor);
  82.     void RemoveMonitor(ODDispatchModule* monitor);
  83.     OrderedCollection* GetMonitors();
  84.  
  85. protected:
  86.     ODDispatchModule* fDispatchModule;
  87.     OrderedCollection* fMonitors;
  88. };
  89.  
  90. //-------------------------------------------------------------------------------------
  91. // DispatchInfo::DispatchInfo
  92. //
  93. // Description
  94. //-------------------------------------------------------------------------------------
  95.  
  96. DispatchInfo::DispatchInfo()
  97. {
  98.     fDispatchModule = kODNULL;
  99.     fMonitors = kODNULL;
  100. }
  101.  
  102. //-------------------------------------------------------------------------------------
  103. // DispatchInfo::~DispatchInfo
  104. //
  105. // Description
  106. //-------------------------------------------------------------------------------------
  107.  
  108. DispatchInfo::~DispatchInfo()
  109. {
  110.     delete fMonitors;
  111.     // Don't delete fDispatchModule, because many entries in the table
  112.     // point to the same module
  113. }
  114.  
  115. //-------------------------------------------------------------------------------------
  116. // DispatchInfo::SetModule
  117. //
  118. // Description
  119. //-------------------------------------------------------------------------------------
  120.  
  121. void DispatchInfo::SetModule(ODDispatchModule* module)
  122. {
  123.     fDispatchModule = module;
  124. }
  125.  
  126. //-------------------------------------------------------------------------------------
  127. // DispatchInfo::GetModule
  128. //
  129. // Description
  130. //-------------------------------------------------------------------------------------
  131.  
  132. ODDispatchModule* DispatchInfo::GetModule()
  133. {
  134.     return fDispatchModule;
  135. }
  136.  
  137. //-------------------------------------------------------------------------------------
  138. // DispatchInfo::AddMonitor
  139. //
  140. // Exceptions thrown:
  141. //         kODErrOutOfMemory
  142. //-------------------------------------------------------------------------------------
  143.  
  144. void DispatchInfo::AddMonitor(ODDispatchModule* monitor)
  145. {
  146.     if (monitor)
  147.     {
  148.         if (!fMonitors)
  149.             fMonitors = new OrderedCollection;
  150.         THROW_IF_NULL(fMonitors);
  151.         
  152.         if (!(fMonitors->Contains((ElementType) monitor)))
  153.             fMonitors->AddLast((ElementType) monitor);
  154.     }
  155. }
  156.     
  157. //-------------------------------------------------------------------------------------
  158. // DispatchInfo::RemoveMonitor
  159. //
  160. // Description
  161. //-------------------------------------------------------------------------------------
  162.  
  163. void DispatchInfo::RemoveMonitor(ODDispatchModule* monitor)
  164. {
  165.     if (fMonitors)
  166.         fMonitors->Remove((ElementType) monitor);
  167. }
  168.  
  169. //-------------------------------------------------------------------------------------
  170. // DispatchInfo::GetMonitors
  171. //
  172. // Description
  173. //-------------------------------------------------------------------------------------
  174.  
  175. OrderedCollection* DispatchInfo::GetMonitors()
  176. {
  177.     return fMonitors;
  178. }
  179.  
  180. //=====================================================================================
  181. // Class DispatchTable
  182. //=====================================================================================
  183.  
  184. //-------------------------------------------------------------------------------------
  185. // DispatchTable::DispatchTable
  186. //
  187. // Constructor. Initializes the array entries to NULL.
  188. //-------------------------------------------------------------------------------------
  189.  
  190. DispatchTable::DispatchTable()
  191. {
  192.     for (short i = 0; i <= kODLastEvent; i++)
  193.         fDispatchInfo[i] = kODNULL;
  194.     fOverflowDispatchInfo = kODNULL;
  195. }
  196.  
  197. //-------------------------------------------------------------------------------------
  198. // DispatchTable::~DispatchTable
  199. //
  200. // Description
  201. //-------------------------------------------------------------------------------------
  202.  
  203. DispatchTable::~DispatchTable()
  204. {
  205.     for (short i = 0; i <= kODLastEvent; i++)    
  206.         delete fDispatchInfo[i];
  207.     //delete[] fDispatchInfo;    // CFront has a problem with this?
  208.     if (fOverflowDispatchInfo)
  209.         fOverflowDispatchInfo->DeleteValues();
  210.     delete fOverflowDispatchInfo;
  211. }
  212.  
  213. //-------------------------------------------------------------------------------------
  214. // DispatchTable::AddMonitor
  215. //
  216. // Description
  217. //-------------------------------------------------------------------------------------
  218.  
  219. void DispatchTable::AddMonitor(ODEventType eventType, 
  220.                                ODDispatchModule* dispatchModule)
  221. {
  222.     // Should check if dispatchModule is already installed as a regular module?
  223.     
  224.     DispatchInfo* info = this->GetDispatchInfo(eventType);
  225.     if (info == kODNULL)
  226.         info = new DispatchInfo;
  227.     THROW_IF_NULL(info);
  228.     info->AddMonitor(dispatchModule);
  229.     
  230.     this->UpdateDispatchInfo(eventType,info);            
  231. }
  232.  
  233. //-------------------------------------------------------------------------------------
  234. // DispatchTable::RemoveMonitor
  235. //
  236. // Description
  237. //-------------------------------------------------------------------------------------
  238.  
  239. void DispatchTable::RemoveMonitor(ODEventType eventType, ODDispatchModule* dispatchModule)
  240. {
  241.     DispatchInfo* info = this->GetDispatchInfo(eventType);
  242.     if (info)
  243.         info->RemoveMonitor(dispatchModule);
  244. }
  245.  
  246. //-------------------------------------------------------------------------------------
  247. // DispatchTable::AddDispatchModule
  248. //
  249. // Description
  250. //-------------------------------------------------------------------------------------
  251.  
  252. void DispatchTable::AddDispatchModule(ODEventType eventType, 
  253.                                ODDispatchModule* dispatchModule)
  254. {
  255.     // To Do: THROW exception if already installed
  256.  
  257.     DispatchInfo* info = this->GetDispatchInfo(eventType);
  258.     
  259.     if (info == kODNULL)
  260.         info = new DispatchInfo;
  261.     THROW_IF_NULL(info);
  262.     info->SetModule(dispatchModule);
  263.     
  264.     this->UpdateDispatchInfo(eventType,info);            
  265. }
  266.  
  267. //-------------------------------------------------------------------------------------
  268. // DispatchTable::RemoveDispatchModule
  269. //
  270. // Description
  271. //-------------------------------------------------------------------------------------
  272.  
  273. void DispatchTable::RemoveDispatchModule(ODEventType eventType)
  274. {
  275.     DispatchInfo* info = this->GetDispatchInfo(eventType);
  276.     if (info)
  277.         info->SetModule(kODNULL);
  278. }
  279.  
  280. //-------------------------------------------------------------------------------------
  281. // DispatchTable::GetDispatchInfo
  282. //
  283. // Description
  284. //-------------------------------------------------------------------------------------
  285.  
  286. DispatchInfo* DispatchTable::GetDispatchInfo(ODEventType eventType)
  287. {
  288.     DispatchInfo* info = kODNULL;
  289.  
  290.     if (eventType <= kODLastEvent)
  291.         info = fDispatchInfo[eventType];
  292.     else if (fOverflowDispatchInfo)
  293.         info = (DispatchInfo*) fOverflowDispatchInfo->ValueAtKey((KeyType) eventType);
  294.     return info;
  295. }
  296.  
  297. //-------------------------------------------------------------------------------------
  298. // DispatchTable::UpdateDispatchInfo
  299. //
  300. // Description
  301. //-------------------------------------------------------------------------------------
  302.     
  303. void DispatchTable::UpdateDispatchInfo(ODEventType eventType, DispatchInfo* info)
  304. {
  305.     if (eventType <= kODLastEvent)
  306.         fDispatchInfo[eventType] = info;
  307.     else
  308.     {
  309.         if (!fOverflowDispatchInfo)
  310.             fOverflowDispatchInfo = new DictionaryList;
  311.         fOverflowDispatchInfo->AddPair((KeyType) eventType, (ValueType) info);
  312.     }
  313. }
  314.  
  315. //-------------------------------------------------------------------------------------
  316. // DispatchTable::GetDispatchModule
  317. //
  318. // Description
  319. //-------------------------------------------------------------------------------------
  320.  
  321. ODDispatchModule* DispatchTable::GetDispatchModule(ODEventType eventType)
  322. {
  323.     ODDispatchModule* module = kODNULL;
  324.     DispatchInfo* info = kODNULL;
  325.     
  326.     if (eventType <= kODLastEvent)
  327.         info = fDispatchInfo[eventType];
  328.     else if (fOverflowDispatchInfo)
  329.         info = (DispatchInfo*) fOverflowDispatchInfo->ValueAtKey((KeyType) eventType);
  330.     if (info)
  331.         module = info->GetModule();
  332.     return module;
  333. }
  334.  
  335. //-------------------------------------------------------------------------------------
  336. // DispatchTable::GetMonitors
  337. //
  338. // Description
  339. //-------------------------------------------------------------------------------------
  340.  
  341. OrderedCollection* DispatchTable::GetMonitors(ODEventType eventType)
  342. {
  343.     OrderedCollection* monitors = kODNULL;
  344.     DispatchInfo* info = kODNULL;
  345.     
  346.     if (eventType <= kODLastEvent)
  347.         info = fDispatchInfo[eventType];
  348.     else if (fOverflowDispatchInfo)
  349.         info = (DispatchInfo*) fOverflowDispatchInfo->ValueAtKey((KeyType) eventType);
  350.     if (info)
  351.         monitors = info->GetMonitors();
  352.     return monitors;
  353. }
  354.  
  355.  
  356.